package topin.facecat.FaceCat.Android

import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.Typeface
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.text.method.PasswordTransformationMethod
import android.util.TypedValue
import android.view.*
import android.view.View.OnFocusChangeListener
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ScrollView
import facecat.topin.core.*
import facecat.topin.div.FCDiv
import facecat.topin.input.FCTextBox
import facecat.topin.xml.FCUIXml
import topin.facecat.FaceCat.MainActivity
import topin.facecat.FaceCat.UI.FCChart


/**
 * 视图
 */
class FCUIView(context: Context?) : ViewGroup(context),
    TextWatcher {
    /*
    * 是否允许滚动
     */
    private var m_allowScroll = true

    /*
     * 是否自动布局
     */
    private val m_autoLayout = true

    /*
     * 编辑中的文本框
     */
    private var m_editingTextBox: FCTextBox? = null

    /*
     * 第一次点击
     */
    private var m_firClick: Long = 0

    /*
     * 获取设置
     */
    /*
         * 对接设备
         */
    var host: AndroidHost? = null
        private set

    /*
     * 纵向滚动值
     */
    private var m_scrollY = 0

    /*
     * 第二次点击
     */
    private var m_secClick: Long = 0

    /*
     * 缩放比例
     */
    var m_scaleFactor = 0.0

    /*
     * 历史输入框
     */
    var m_textBox: EditText? = null

    /*
     * 获取方法库
     */
    var native: FCNative? = null
        private set

    /*
     * 获取绘图对象
     */
    var paint: AndroidPaint? = null
        private set

    val rate: Double
        get() = host!!.scaleRate

    /*
     * 是否允许滚动
     */
    private var m_scrollEnabled = true

    /*
     * 滚动视图
     */
    private var m_scrollView: ScrollView? = null

    /*
     * 点击次数
     */
    private var m_touchCount = 0

    /*
     * 设置是否允许滚动
     */
    fun setAllowScroll(allowScroll: Boolean) {
        m_allowScroll = allowScroll
    }

    /*
     * 上次焦点的视图
     */
    var m_lastFocusedView: FCView? = null

    /**
     * 设置滚动视图
     * @param view 视图
     */
    fun setScrollView(view: ScrollView?) {
        m_scrollView = view
        m_scrollView!!.setOnTouchListener(object : OnTouchListener {
            override fun onTouch(v: View, event: MotionEvent): Boolean {
                return if (m_allowScroll && m_scrollEnabled) {
                    false
                } else {
                    try {
                        val action = event.action
                        if (action == MotionEvent.ACTION_MOVE) {
                            val x = event.x
                            val y = event.y + m_scrollView!!.scrollY
                            host!!.touchPoint = FCPoint(x, y)
                            val touchInfo = FCTouchInfo()
                            host!!.getTouches(event, touchInfo)
                            touchInfo.m_clicks = m_lastClickCount
                            native!!.onTouchMove(touchInfo)
                        } else {
                            if (action == MotionEvent.ACTION_UP) {
                                m_scrollEnabled = true
                                val x = event.x
                                val y = event.y + m_scrollView!!.scrollY
                                host!!.touchPoint = FCPoint(x, y)
                                val touchInfo = FCTouchInfo()
                                host!!.getTouches(event, touchInfo)
                                touchInfo.m_clicks = m_lastClickCount
                                native!!.onTouchEnd(touchInfo)
                            }
                        }
                    } catch (ex: Exception) {
                    }
                    true
                }
            }
        })
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 文字改变
     * @param s 参数
     */
    override fun afterTextChanged(s: Editable) {}

    /**
     * 文字改变前
     * @param s
     * @param start
     * @param count
     * @param after
     */
    override fun beforeTextChanged(
        s: CharSequence,
        start: Int,
        count: Int,
        after: Int
    ) {
    }

    /**
     * 处理键盘事件
     * @param event
     * @return
     */
    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        if (event.keyCode == KeyEvent.KEYCODE_ENTER) {
            hideTextBox(m_editingTextBox)
        }
        return super.dispatchKeyEvent(event)
    }

    /**
     * 删除资源
     */
    fun delete() {
        if (host != null) {
            host!!.m_threadState = 2
        }
        if (native != null) {
            (native as FCNative).delete()
        }
        native = null
        paint = null
        host = null
        m_textBox = null
        m_editingTextBox = null
        m_scrollView = null
    }

    /**
     * 隐藏本文框
     * @param textBox 文本框
     */
    fun hideTextBox(textBox: FCDiv?) {
        try {
            if (textBox as? FCTextBox != null) {
                if (m_textBox != null && m_textBox!!.parent != null && textBox != null) {
                    textBox.isFocused = false
                    textBox.onLostFocus()
                    val text = m_textBox!!.text.toString()
                    textBox.text = text
                    val textLength = text.length
                    if (textLength > 0) {
                        val old1 =
                            (if (m_editingTextBox is FCTextBox) m_editingTextBox else null)
                        if (old1 != null) {
                            old1.selectionLength = 0
                            old1.selectionStart = textLength + 1
                        }
                    }
                    native!!.invalidate()
                    m_editingTextBox = null
                    try {
                        m_textBox!!.clearFocus()
                        if (!m_allowScroll) {
                            m_scrollView!!.scrollTo(0, 0)
                        }
                        if (m_scrollView != null) {
                            m_scrollView!!.scrollTo(0, m_scrollY - 300)
                        }
                    } catch (ex: Exception) {
                    }
                }
                m_editingTextBox = null
                removeView(m_textBox)
                layout(0, 0, width, height)
            }
        } catch (ex: Exception) {
        }
    }

    /*
    * 上次点击次数
     */
    var m_lastClickCount = 0

    /*
    * 上次的坐标
     */
    var m_lastPoint = FCPoint()

    /**
     * 手指按下
     */
    private fun onActionDown(event: MotionEvent) {
        try {
            this.requestFocus()
            if (native != null) {
                var touchCount = 1
                val x = event.x
                val y = event.y
                val pointerCount = event.pointerCount
                if (pointerCount == 1) {
                    m_touchCount++
                    if (m_touchCount == 1) {
                        m_firClick = System.currentTimeMillis()
                    } else if (m_touchCount == 2) {
                        m_secClick = System.currentTimeMillis()
                        if (m_secClick - m_firClick < 800 && Math.abs(x - m_lastPoint.x) < width / 50 && Math.abs(
                                y - m_lastPoint.y
                            ) < height / 50
                        ) {
                            touchCount = 2
                            m_touchCount = 0
                            m_firClick = 0
                            m_secClick = 0
                        } else {
                            touchCount = 1
                            m_touchCount = 1
                            m_firClick = System.currentTimeMillis()
                        }
                    } else {
                        m_touchCount = 0
                        touchCount = 1
                    }
                } else {
                    m_touchCount = 0
                    touchCount = 1
                }
                if (touchCount == 0) {
                    touchCount = 1
                    m_touchCount = 0
                }
                val oldFocusedControl = native!!.focusedView
                host!!.touchPoint = FCPoint(x, y)
                val touchInfo = FCTouchInfo()
                host!!.getTouches(event, touchInfo)
                touchInfo.m_clicks = touchCount
                native!!.onTouchBegin(touchInfo)
                //ArrayList<CTouch> cTouches = new ArrayList<>();
                //m_host.GetTouches(event, cTouches);
                //m_native.OnTouchBegin(cTouches);
                val newFocusedControl = native!!.focusedView
                m_newFocusedView = newFocusedControl
                var scrollEnabled = true
                if (m_scrollView != null && newFocusedControl != null) {
                    if (newFocusedControl.allowDrag()) {
                        scrollEnabled = false
                    } else {
                        var chart =
                            newFocusedControl as? FCChart
                        var parentIsChart = false
                        if (chart == null && newFocusedControl.parent != null) {
                            chart =
                                (if (newFocusedControl.parent is FCChart) newFocusedControl.parent else null) as FCChart?
                            parentIsChart = true
                        }
                        if (chart != null) {
                            if (parentIsChart) {
                                scrollEnabled = false
                            } else {
                                /*if (chart.isOperating || chart.showCrossLine()) {
                                    scrollEnabled = false
                                }*/
                            }
                        }
                        var previewsControl = host!!.findPreviewsControl(newFocusedControl)
                        if (previewsControl == null) {
                            previewsControl = newFocusedControl
                        }
                        val div =
                            previewsControl as? FCDiv
                        if (div != null && div.allowDragScroll()) {
                            if (div.vScrollBar != null && div.vScrollBar
                                    .isVisible || div.hScrollBar != null && div.hScrollBar
                                    .isVisible
                            ) {
                                scrollEnabled = false
                            }
                        }
                    }
                }
                m_scrollEnabled = scrollEnabled
                val mousePoint = host!!.touchPoint
                var oldTextBox: FCDiv? = null
                if (oldFocusedControl != null) {
                    oldTextBox =
                            oldFocusedControl as? FCTextBox
                }
                var showTextBox = false
                if (newFocusedControl != null) {
                    if (m_editingTextBox != null) {
                        hideTextBox(m_editingTextBox)
                    }
                    val textBox =
                            newFocusedControl as? FCTextBox
                    if (textBox != null && textBox.isEnabled && !textBox.isReadOnly) {
                        m_editingTextBox = textBox
                        //m_editingTextBox->SetFocused(false);
                        ShowTextBox(m_editingTextBox)
                        showTextBox = true
                    }
                }
                if (!showTextBox) {
                    hideTextBox(oldTextBox)
                }
                native!!.invalidate()
                //cTouches.clear();
            }
        } catch (ex: Exception) {
        }
    }

    /*
    * 新的焦点视图
     */
    var m_newFocusedView: FCView? = null

    var thisLock = Any()

    /**
     * 手指按下 -> 手指移动
     */
    private fun onActionMove(event: MotionEvent) {
        try {
            val x = event.x
            val y = event.y
            host!!.touchPoint = FCPoint(x, y)
            val newFocusedControl = native!!.focusedView
            var scrollEnabled = true
            if (m_scrollView != null && newFocusedControl != null) {
                if (newFocusedControl.allowDrag()) {
                    scrollEnabled = false
                } else {
                    var chart: FCChart? = null
                    var parentIsChart = false
                    if (newFocusedControl is FCChart) {
                        chart = newFocusedControl
                    } else {
                        val tempControl = newFocusedControl.parent
                        if (tempControl != null && tempControl is FCView) {
                            chart = tempControl as FCChart
                            parentIsChart = true
                        }
                    }
                    if (chart != null) {
                        if (parentIsChart) {
                            scrollEnabled = false
                        } else {
                            /*if (chart.isOperating || chart.showCrossLine()) {
                                scrollEnabled = false
                            }*/
                        }
                    }
                    var previewsControl = host!!.findPreviewsControl(newFocusedControl)
                    if (previewsControl == null) {
                        previewsControl = newFocusedControl
                    }
                    if (previewsControl is FCDiv) {
                        val div = previewsControl
                        if (div.allowDragScroll()) {
                            val scrollBarA = div.vScrollBar
                            val hScrollBarA = div.hScrollBar
                            if (scrollBarA != null && scrollBarA.isVisible || hScrollBarA != null && hScrollBarA.isVisible) {
                                scrollEnabled = false
                            }
                        }
                    }
                }
            }
            m_scrollEnabled = scrollEnabled
            val touchInfo = FCTouchInfo()
            host!!.getTouches(event, touchInfo)
            touchInfo.m_clicks = m_lastClickCount
            native!!.onTouchMove(touchInfo)
        } catch (ex: Exception) {
        }
        //ArrayList<CTouch> cTouches = new ArrayList<>();
        //_host.GetTouches(event, cTouches);
        //m_native.OnTouchMove(cTouches);
        //cTouches.clear();
    }

    /**
     * 手指按下 -> 手指抬起
     */
    private fun onActionUp(event: MotionEvent, cancel: Boolean) {
        try {
            val x = event.x
            val y = event.y
            host!!.touchPoint = FCPoint(x, y)
            val touchInfo = FCTouchInfo()
            host!!.getTouches(event, touchInfo)
            touchInfo.m_clicks = m_lastClickCount
            if (cancel) {
                native!!.onTouchCancel(touchInfo)
            } else {
                native!!.onTouchEnd(touchInfo)
            }
            m_lastFocusedView = m_newFocusedView
        } catch (ex: Exception) {
        }
    }

    /**
     * 绘图方法
     * @param canvas
     */
    override fun onDraw(canvas: Canvas) {
        if (host != null) {
            host!!.onPaint(canvas)
        }
    }

    /**
     * 加载视图
     */
    fun onLoad() {
        host = AndroidHost()
        native = FCNative()
        paint = AndroidPaint()
        native!!.host = host
        native!!.paint = paint
        native!!.resourcePath = ""
        host!!.native = native!!
        host!!.view = this
        native!!.size = FCSize(width, height)
    }

    /*
     * 获取XML对象
     *//*
     * 设置XML对象
     */
    var loadUI: FCUIXml? = null

    private var m_uiIsLoaded = false

    /*
     * 获取缩放比例
     *//*
     * 设置缩放比例
     */
    var scaleFactor: Double
        get() = m_scaleFactor
        set(scaleFactor) {
            m_scaleFactor = scaleFactor
            resetLayout()
        }

    var m_xmlStr = ""

    /**
     * 重置布局
     */
    fun resetLayout() {
        if (native != null) {
            if (m_scaleFactor == 0.0) {
                m_scaleFactor = if (m_autoLayout) {
                    host!!.scaleRate
                } else {
                    1.0
                }
            }
            val rate = m_scaleFactor
            if (rate != 1.0) {
                native!!.setAllowScaleSize(true)
                native!!.scaleSize = FCSize(
                    (width / rate).toInt(),
                    (height / rate).toInt()
                )
                native!!.size = FCSize(width, height)
                //m_native.onScaling(rate, rate);
                native!!.update()
            } else {
                native!!.setAllowScaleSize(false)
                native!!.size = FCSize(width, height)
                native!!.update()
            }
            if (!m_uiIsLoaded) {
                if (loadUI != null) {
                    loadUI!!.native = native
                    setAllowScroll(false)
                    //m_loadUI.getNative().setSize(m_native.getSize());
                    loadUI!!.loadXml(m_xmlStr, null)
                }
                native!!.update()
                m_uiIsLoaded = true
            }
            //m_native.invalidate();
        }
    }

    /**
     * 加载布局
     * @param changed
     * @param left
     * @param top
     * @param right
     * @param bottom
     */
    override fun onLayout(
        changed: Boolean,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int
    ) {
        if (changed) {
            resetLayout()
        }
    }

    /**
     * 文本改变事件
     * @param s
     * @param start
     * @param before
     * @param count
     */
    override fun onTextChanged(
        s: CharSequence,
        start: Int,
        before: Int,
        count: Int
    ) {
        val allTextInTextBox = s.toString()
        if (m_editingTextBox != null) {
            m_editingTextBox!!.text = allTextInTextBox
        }
    }

    /**
     * 触摸事件
     * @param event
     * @return
     */
    override fun onTouchEvent(event: MotionEvent): Boolean {
        val action = event.action
        when (action) {
            MotionEvent.ACTION_MOVE -> {
                onActionMove(event)
                return false
            }
            MotionEvent.ACTION_DOWN -> onActionDown(event)
            MotionEvent.ACTION_UP -> onActionUp(event, false)
            MotionEvent.ACTION_CANCEL -> {
                val mouseDownControl = native!!.pushedView
                if (mouseDownControl != null) {
                    //mouseDownControl.onTouchCancel(null);
                }
            }
        }
        return true
    }

    /**
     * 窗体高度
     */
    private var m_WindowHeight = 0
    var onGlobalLayoutListener: OnGlobalLayoutListener? = null

    /**
     * 软键盘监听
     */
    fun addOnSoftKeyBoardVisibleListener() {
        if (onGlobalLayoutListener == null) {
            val decorView: View =
                MainActivity.m_mainActivity!!.window.decorView
            onGlobalLayoutListener = OnGlobalLayoutListener {
                val r = Rect()
                //获取当前窗口实际的可见区域
                decorView.getWindowVisibleDisplayFrame(r)
                val height = r.height()
                if (m_WindowHeight == 0) {
                    //一般情况下，这是原始的窗口高度
                    m_WindowHeight = height
                } else {
                    if (m_WindowHeight != height) {
                        //两次窗口高度相减，就是软键盘高度
                        val softKeyboardHeight = m_WindowHeight - height
                        if (m_editingTextBox != null && m_textBox != null) {
                            if (m_textBox!!.bottom > getHeight() - softKeyboardHeight) {
                                layout(
                                    0,
                                    -softKeyboardHeight,
                                    width,
                                    getHeight() - softKeyboardHeight
                                )
                            }
                        }
                    }
                }
            }
            decorView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener)
        }
    }

    /**
     * 显示文本框
     * @param textBox 文本框
     */
    fun ShowTextBox(textBox: FCTextBox?) {
        try {
            addOnSoftKeyBoardVisibleListener()
            if (textBox == null) {
                return
            }
            var scaleFactorX = 1f
            var scaleFactorY = 1f
            if (native!!.allowScaleSize()) {
                val scaleSize = native!!.scaleSize
                val host = host
                val size = host!!.clientSize
                if (size.cx > 0 && size.cy > 0) {
                    scaleFactorX = scaleSize.cx.toFloat() / size.cx
                    scaleFactorY = scaleSize.cy.toFloat() / size.cy
                }
            }
            var subWidth = 0
            val subControls = textBox.views
            val subControlsSize = subControls.size
            for (i in 0 until subControlsSize) {
                val control = subControls[i]
                if (control.isVisible) {
                    subWidth += control.width
                }
            }
            val clientX = textBox.native.clientX(textBox) + textBox.padding.left - 1
            var inTop = false
            val x = ((clientX + 1) / scaleFactorX).toInt()
            val clientY = textBox.native.clientY(textBox)
            var cx =
                ((textBox.width - subWidth - textBox.padding.right - 2) / scaleFactorX).toInt()
            if (textBox.padding.right > 0) {
                cx =
                    ((textBox.width - subWidth - textBox.padding.right) / scaleFactorX).toInt()
            }
            if (clientY > textBox.native.size.cy * 3 / 5) {
                /*clientY = getNative().getSize().cy / 2 - 50;
                if(clientY < 30){
                    clientY = 30;
                }
                cx = (int)(textBox.getNative().getSize().cx / scaleFactorX) - 20;
                x = 10;
                inTop = true;*/
                inTop = true
            }
            val y = ((clientY + 2) / scaleFactorY).toInt()
            val cy = ((textBox.height - 4) / scaleFactorY).toInt()
            var isNew = false
            if (m_textBox == null) {
                m_textBox = EditText(context)
                m_textBox!!.setSingleLine()
                m_textBox!!.gravity = Gravity.LEFT
                isNew = true
            }
            val fontFamily = textBox.font.m_fontFamily
            var newFont = ""
            newFont = if (fontFamily == "Default") {
                val sysFont = "System"
                if (sysFont == "System") {
                    "Default"
                } else {
                    sysFont
                }
            } else {
                fontFamily
            }
            if (newFont == "Default") {
                m_textBox!!.setTypeface(Typeface.DEFAULT)
            } else {
                try {
                    val tf = Typeface.createFromFile("/system/fonts/$newFont.ttf")
                    if (tf != null) {
                        m_textBox!!.setTypeface(tf)
                    }
                } catch (ex: Exception) {
                }
            }
            m_textBox!!.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                (textBox.font.m_fontSize / ((scaleFactorX + scaleFactorY) / 2))
            )
            val androidPaint = paint
            m_textBox!!.setBackgroundColor(androidPaint!!.getAndriodColor(textBox.backColor))
            m_textBox!!.setTextColor(androidPaint.getAndriodColor(textBox.textColor))
            if (m_textBox!!.parent == null) {
                addView(m_textBox)
            }
            var isPwd = false
            val text = textBox.text
            if (isNew) {
                m_textBox!!.addTextChangedListener(this)
            }
            val txt1 = textBox
            if (txt1 != null && txt1.passwordChar != '\u0000') {
                isPwd = true
                m_textBox!!.inputType =
                    InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
            } else {
                m_textBox!!.inputType = InputType.TYPE_TEXT_FLAG_MULTI_LINE
            }
            val value = RefObject(String())
            m_textBox!!.setText(text)
            //m_textBox.setTextSize(textBox.getFont().m_fontSize);
            m_textBox!!.isAllCaps = true
            m_textBox!!.isClickable = true
            m_textBox!!.setTextIsSelectable(true)
            val cornerRadis = textBox.cornerRadius
            m_textBox!!.layout(
                x + (cornerRadis * scaleFactorX).toInt(),
                y + (cornerRadis * scaleFactorY).toInt(),
                x + cx - (cornerRadis * scaleFactorX).toInt(),
                y + cy - (cornerRadis * scaleFactorY).toInt()
            )
            m_textBox!!.animate()
            m_textBox!!.setSelection(text.length)
            //m_textBox.setGravity(Gravity.CENTER);
            val oldScrolly = m_scrollY
            if (m_scrollView != null) {
                m_scrollY = y - 200
                m_scrollView!!.scrollTo(0, m_scrollY)
            }
            m_textBox!!.isFocusable = true
            m_textBox!!.isCursorVisible = true
            m_textBox!!.isFocusableInTouchMode = true
            m_textBox!!.requestFocus()
            m_textBox!!.setPadding(0, 15, 0, 0)
            if(isPwd) {
                m_textBox!!.transformationMethod = PasswordTransformationMethod.getInstance()
            }
            val inputManager = m_textBox!!.context
                .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            inputManager.showSoftInput(m_textBox, 0)
            m_textBox!!.onFocusChangeListener = OnFocusChangeListener { view, b ->
                if (!b) {
                    inputManager.hideSoftInputFromWindow(windowToken, 0)
                    if (m_scrollView != null) {
                        m_scrollView!!.scrollTo(0, oldScrolly)
                    }
                }
            }
            //MainActivity.m_mainActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        } catch (ex: Exception) {
        }
    }

    /**
     * 构造函数
     * @param context 上下文
     */
    init {
        setWillNotDraw(false)
    }
}